/*
*	Created:			09.03.10
*	Author:				009
*	Last Modifed:		-
*/

// SDK
#include "SDK/amx/amx.h"
#include "SDK/plugincommon.h"
// core
#include "math.h"
#include <stdio.h>
#include <stddef.h>
// plugin
#include "os.h"
#include "main.h"
// npc core
#include "NPC class.h"
// samp data
#include "samp address.h"
#include "samp defines.h"
#include "samp structs.h"
#include "SyncStructs.h"

extern	CNPC*	NPC[MAX_NPCS];
// main vars
extern DWORD	c_samp;
extern DWORD	c_players;
extern DWORD	c_vehicles;
extern DWORD	CSampPointer;

// addr
extern DWORD	CPlayerPosXOffset;
extern DWORD	CPlayerPosYOffset;
extern DWORD	CPlayerPosZOffset;
extern DWORD	CPlayerHealthOffset;
extern DWORD	CPlayerArmourOffset;
extern DWORD	CPlayerAngleOffset;
extern DWORD	CPlayerStateOffset;
extern DWORD	CPlayerFootSyncOffset;
extern DWORD	CPlayerInCarSyncOffset;
extern DWORD	CPlayerPassangerSyncOffset;
extern DWORD	CPlayerAimSyncOffset;
extern DWORD	CPlayerAimSyncStateOffset;
extern DWORD	CPlayerSyncTypeOffset;
extern DWORD	CPlayerWeaponSkillOffset;
extern DWORD	CPlayerSkinOffset;
extern DWORD	CPlayerInteriorOffset;
extern DWORD	CPlayerIsStreamedOffset;
extern DWORD	CPlayerVehicleIdOffset;
extern DWORD	CPlayerVehicleSeatOffset;

extern DWORD	CVehiclePosXOffset;
extern DWORD	CVehiclePosYOffset;
extern DWORD	CVehiclePosZOffset;
extern DWORD	CVehicleDriverOffset;
extern DWORD	CVehicleModelOffset;
extern DWORD	CVehicleHealthOffset;

// other
extern	int		WeaponReload[MAX_PLAYERS];
extern	int		WeaponsReloadTime[MAX_WEAPONS + 1];

bool FireComplete[MAX_PLAYERS];

int EndAgility[MAX_PLAYERS];
int StartAgility[MAX_PLAYERS];
int Attacked[MAX_PLAYERS];

// utils functions
bool IsProjectileWeapon(int weaponid);
bool IsShotWeapon(int weaponid);
bool IsMeeleWeapon(int weaponid);

bool IsInRange(float x,float y,float z,float range);
void VectorByRotate(float x_r,float y_r,float z_r,float *x,float *y,float *z);
float Roll2Grad(float roll);
float Grad2Roll(float grad);

bool IsRhinoVehicle(int model);
bool IsHydraVehicle(int model);
bool IsHunterVehicle(int model);
bool IsCarVehicle(int model);
bool IsBikeVehicle(int model);

THREAD_START(NPCDamageThread){
	float	health;
	float	tmp_x;
	float	tmp_y;
	float	tmp_z;
	float	f_x;
	float	f_y;
	float	f_z;
	float	u_x;
	float	u_y;
	float	u_z;
	float	angle;
	float	cosa;
	float	sina;
	//
	int		pid;
	int		npcid;
	int		keystate;
	int		weapon;
	DWORD	c_player;
	//
	int		type;
	int		vehicle;
	DWORD	c_vehicle;
	int		model;
	// knock
	float	pos_x;
	float	pos_y;
	float	pos_z;
	float	v_x;
	float	v_y;
	float	v_z;
	int		check_knock;
	// 
	float	range[3];
	//
	//int ticks;
	//
	// reset
	for(pid = 0;pid < MAX_PLAYERS;pid++)
	{
		Attacked[pid] = 0;
		StartAgility[pid] = 0;
		EndAgility[pid] = 0;
	}
	// wait
	while(!c_samp) SLEEP(100);
	// thread
	while(true)
	{
		for(pid = 0;pid < MAX_PLAYERS;pid++)
		{
			// if connected
			if(!*(DWORD*)(c_players + pid*4)) continue;
			// struct addr
			c_player = *(DWORD*)(c_players + pid*4 + C_PLAYERS_PLAYER_OFFSET);
			// keystate null
			keystate = 0;		
			// null type
			type = 0;
			// null knock
			check_knock = 0;
			// switch driver and passanger
			switch(*(BYTE*)(c_player + CPlayerStateOffset))
			{
			case PLAYER_STATE_DRIVER:
				{
					// get vehicle
					vehicle = *(unsigned short*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,VehicleId));					
					// get vehicle struct
					c_vehicle = *(DWORD*)(c_vehicles + vehicle*4 + C_VEHICLES_VEHICLE_OFFSET);
					// get knock data
					// pos
					pos_x = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosX));
					pos_y = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosY));
					pos_z = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosZ));
					// velocity
					v_x = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,VelocityX));
					v_y = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,VelocityY));
					v_z = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,VelocityZ));
					// set knock
					check_knock = 1;
					// check vehicle
					if(!c_vehicle) continue;
					// get vehicle model
					model = *(DWORD*)(c_vehicle + CVehicleModelOffset);
					// if army vehicle
					if(IsRhinoVehicle(model))
					{
						// if shoot
						if((*(unsigned short*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,KeysOther)) & KEY_FIRE) == 0) 
						{
							if(Attacked[pid] != 0) Attacked[pid] = 0;
							break;
						}
						// if fire completed
						if(Attacked[pid] != 0) break;
						// get coords
						tmp_x = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosX));
						tmp_y = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosY));
						tmp_z = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosZ)) + 1.6; // z correct in rhino 1.6
						// get roll
						f_x = *(FLOAT*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,FrontVectorX));
						f_y = *(FLOAT*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,FrontVectorY));
						f_z = *(FLOAT*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,FrontVectorZ)) + 0.23; // z correct in rhino 0.23
						// get weapon
						weapon = 47;
						// set type
						type = DAMAGE_TYPE_RAKET_FROM_VEHICLE; // radius 5.0 , vector f_x,f_y,f_z
						// complete
						Attacked[pid] = 1;
					}
					else if(IsHydraVehicle(model)) // if hydra
					{
						// if shoot
						if((*(unsigned short*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,KeysOther)) & KEY_ACTION) == 0) 
						{
							if(Attacked[pid] != 0) Attacked[pid] = 0;
							break;
						}
						// if fire completed
						if(Attacked[pid] != 0) break;
						// get coords
						tmp_x = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosX));
						tmp_y = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosY));
						tmp_z = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosZ));
						// get roll
						u_x = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,QuaternionX));
						u_y = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,QuaternionY));
						u_z = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,QuaternionZ));
						// create vector from roll
						VectorByRotate(Roll2Grad(u_x),Roll2Grad(u_y),Roll2Grad(u_z),&f_x,&f_y,&f_z);
						// get weapon
						weapon = 47;
						// set type
						type = DAMAGE_TYPE_RAKET_FROM_VEHICLE; // radius 5.0 , vector f_x,f_y,f_z
						// complete
						Attacked[pid] = 1;					
					} 
					else if(IsHunterVehicle(model)) // if hunter
					{
						// if shoot raket
						if((*(unsigned short*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,KeysOther)) & KEY_FIRE)) 
						{
							// if fire completed
							if(Attacked[pid] != 0) break;
							// get coords
							tmp_x = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosX));
							tmp_y = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosY));
							tmp_z = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosZ));
							// get roll
							u_x = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,QuaternionX));
							u_y = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,QuaternionY));
							u_z = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,QuaternionZ));
							// create vector from roll
							VectorByRotate(Roll2Grad(u_x),Roll2Grad(u_y),Roll2Grad(u_z),&f_x,&f_y,&f_z);
							// get weapon
							weapon = 47;
							// set type
							type = DAMAGE_TYPE_RAKET_FROM_VEHICLE; // radius 5.0 , vector f_x,f_y,f_z
							// complete
							Attacked[pid] = 1;
						}
						else if(Attacked[pid] != 0) Attacked[pid] = 0;
						// if shoot bullet
						if((*(unsigned short*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,KeysOther)) & KEY_ACTION))
						{
							// reload
							if(WeaponReload[pid] > 0) break;
							// get coords
							tmp_x = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosX));
							tmp_y = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosY));
							tmp_z = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosZ));
							// get roll
							u_x = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,QuaternionX));
							u_y = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,QuaternionY));
							u_z = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,QuaternionZ));
							// create vector from roll
							VectorByRotate(Roll2Grad(u_x),Roll2Grad(u_y),Roll2Grad(u_z),&f_x,&f_y,&f_z);
							// get weapon
							weapon = 31;
							// set type
							type = DAMAGE_TYPE_BULLET_FROM_VEHICLE; // radius 1.0 , vector f_x,f_y,f_z
							// reload time
							WeaponReload[pid] = WeaponsReloadTime[weapon];
						}
					} 
					else if(IsCarVehicle(model)) // if car
					{
						// reload
						if(WeaponReload[pid] > 0) break;
						// if shoot
						if((*(unsigned short*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,KeysOther)) & KEY_FIRE) == 0) break;
						// is not reload
						if((*(BYTE*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,WeaponState))) == WEAPONSTATE_RELOADING) break;
						// is not lost bullet
						if((*(BYTE*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,WeaponState))) == WEAPONSTATE_NO_BULLETS) break;
						// if right or left
						if(*(unsigned short*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,KeysOther)) & KEY_LOOK_LEFT) angle = 90.0;
						else if(*(unsigned short*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,KeysOther)) & KEY_LOOK_RIGHT) angle = -90.0;
						else continue;
						// get weapon
						weapon = *(BYTE*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PlayerWeapon));
						// if have shot gun
						if(weapon == 0) break;
						// get coords
						tmp_x = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosX));
						tmp_y = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosY));
						tmp_z = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosZ));
						// get roll
						u_x = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,QuaternionX));
						u_y = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,QuaternionY));
						u_z = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,QuaternionZ));
						// create vector from roll
						VectorByRotate(Roll2Grad(u_x),Roll2Grad(u_y),Roll2Grad(u_z) + angle,&f_x,&f_y,&f_z);
						// set type
						type = DAMAGE_TYPE_BULLET_FROM_VEHICLE; // radius 1.0 , vector f_x,f_y,f_z
						// reload time
						WeaponReload[pid] = WeaponsReloadTime[weapon];
					} 
					else if(IsBikeVehicle(model)) // if bike
					{
						// reload
						if(WeaponReload[pid] > 0) break;
						// if shoot
						if((*(unsigned short*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,KeysOther)) & KEY_FIRE) == 0) break;
						// is not reload
						if((*(BYTE*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,WeaponState))) == WEAPONSTATE_RELOADING) break;
						// is not lost bullet
						if((*(BYTE*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,WeaponState))) == WEAPONSTATE_NO_BULLETS) break;
						// if right or left or front
						if(*(unsigned short*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,KeysOther)) & KEY_LOOK_LEFT) angle = 90.0;
						else if(*(unsigned short*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,KeysOther)) & KEY_LOOK_RIGHT) angle = -90.0;
						else angle = 0.0;
						// get weapon
						weapon = *(BYTE*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PlayerWeapon));
						// if have shot gun
						if(weapon == 0) break;
						// get coords
						tmp_x = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosX));
						tmp_y = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosY));
						tmp_z = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,PosZ));
						// get roll
						u_x = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,QuaternionX));
						u_y = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,QuaternionY));
						u_z = *(FLOAT*)(c_player + CPlayerInCarSyncOffset + offsetof(InCarSync,QuaternionZ));
						// create vector from roll
						VectorByRotate(Roll2Grad(u_x),Roll2Grad(u_y),Roll2Grad(u_z) + angle,&f_x,&f_y,&f_z);
						// set type
						type = DAMAGE_TYPE_BULLET_FROM_VEHICLE; // radius 1.0 , vector f_x,f_y,f_z
						// reload time
						WeaponReload[pid] = WeaponsReloadTime[weapon];
					}
					break;
				}
			case PLAYER_STATE_PASSENGER:
				{
					// reload
					if(WeaponReload[pid] > 0) break;
					// if shoot
					if((*(unsigned short*)(c_player + CPlayerPassangerSyncOffset + offsetof(PassangerSync,KeysOther)) & KEY_FIRE) == 0) break;
					// is not reload
					if((*(BYTE*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,WeaponState))) == WEAPONSTATE_RELOADING) break;
					// is not lost bullet
					if((*(BYTE*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,WeaponState))) == WEAPONSTATE_NO_BULLETS) break;
					// get vehicle
					vehicle = *(unsigned short*)(c_player + CPlayerPassangerSyncOffset + offsetof(PassangerSync,VehicleId));
					// get vehicle struct
					c_vehicle = *(DWORD*)(c_vehicles + vehicle*4 + C_VEHICLES_VEHICLE_OFFSET);
					// check vehicle
					if(!c_vehicle) continue;
					// get vehicle model
					model = *(DWORD*)(c_vehicle + CVehicleModelOffset);
					// if bike or car
					if((IsCarVehicle(model) == 0) && (IsBikeVehicle(model) == 0)) break;
					// get weapon
					weapon = *(BYTE*)(c_player + CPlayerPassangerSyncOffset + offsetof(PassangerSync,Weapon));
					// get coords
					tmp_x = *(FLOAT*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,PosX));
					tmp_y = *(FLOAT*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,PosY));
					tmp_z = *(FLOAT*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,PosZ));
					// get vector
					f_x = *(FLOAT*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,FrontVectorX));
					f_y = *(FLOAT*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,FrontVectorY));
					f_z = *(FLOAT*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,FrontVectorZ));
					// set type
					type = DAMAGE_TYPE_BULLET_FROM_PASSENGER; // radius 0.5 , vector f_x,f_y,f_z
					// reload time
					WeaponReload[pid] = WeaponsReloadTime[weapon];
					break;
				}
			case PLAYER_STATE_ONFOOT:
				{
					// reload
					if(WeaponReload[pid] > 0) break;
					// if sprint
					if(*(unsigned short*)(c_player + CPlayerFootSyncOffset + offsetof(OnFootSync,KeysOther)) & KEY_SPRINT) break;
					// get key state
					keystate = ((*(unsigned short*)(c_player + CPlayerFootSyncOffset + offsetof(OnFootSync,KeysOther)) & KEY_FIRE) != 0);
					// is not reload
					if((*(BYTE*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,WeaponState))) == WEAPONSTATE_RELOADING) break;
					// is not lost bullet
					if((*(BYTE*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,WeaponState))) == WEAPONSTATE_NO_BULLETS) break;
					// get weapon
					weapon = *(BYTE*)(c_player + CPlayerFootSyncOffset + offsetof(OnFootSync,PlayerWeapon));
					// if pressed
					if(keystate)
					{
						if(IsProjectileWeapon(weapon)) // grenades
						{
							if(Attacked[pid] == 0)
							{
								if(StartAgility[pid] == 0)
								{
									StartAgility[pid] = GetTickCount();
									EndAgility[pid] = GetTickCount();
								}
								else EndAgility[pid] = GetTickCount();
							}
						}
						else if(IsMeeleWeapon(weapon)) // meele
						{
							if(Attacked[pid] == 0)
							{
								// get current pos
								tmp_x = *(FLOAT*)(c_player + CPlayerFootSyncOffset + offsetof(OnFootSync,PosX));
								tmp_y = *(FLOAT*)(c_player + CPlayerFootSyncOffset + offsetof(OnFootSync,PosY));
								tmp_z = *(FLOAT*)(c_player + CPlayerFootSyncOffset + offsetof(OnFootSync,PosZ));
								angle = *(FLOAT*)(c_player + CPlayerAngleOffset) * 0.0174532925199433;
								// move coords
								tmp_x += (1.0 * sin(-angle));
								tmp_y += (1.0 * cos(-angle));
								// reload
								WeaponReload[pid] = WeaponsReloadTime[weapon];
								// type
								type = DAMAGE_TYPE_MEELE;
							}
						}
						else
						{
							// get coords
							tmp_x = *(FLOAT*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,PosX));
							tmp_y = *(FLOAT*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,PosY));
							tmp_z = *(FLOAT*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,PosZ));
							// get vector front
							f_x = *(FLOAT*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,FrontVectorX));
							f_y = *(FLOAT*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,FrontVectorY));
							f_z = *(FLOAT*)(c_player + CPlayerAimSyncOffset + offsetof(AimSync,FrontVectorZ));
							if(IsShotWeapon(weapon)) // bullet weapons
							{
								// type
								type = DAMAGE_TYPE_BULLET;
							}
							else // raket
							{
								// type
								type = DAMAGE_TYPE_RAKET;
							}
							// reload
							WeaponReload[pid] = WeaponsReloadTime[weapon];
						}
					}
					else if(Attacked[pid] == 1) Attacked[pid] = 0;

					if(((StartAgility[pid] != 0) && (keystate == 0)) || ((EndAgility[pid] - StartAgility[pid]) >= PROJECTILE_MAX_AGILITY))
					{
						EndAgility[pid] -= StartAgility[pid];
						if(EndAgility[pid] > PROJECTILE_MAX_AGILITY) EndAgility[pid] = PROJECTILE_MAX_AGILITY;
						// dist
						f_x = PROJECTILE_START_DIST + (PROJECTILE_DIST_BY_AGILITY * EndAgility[pid]);
						// angle
						f_y = *(FLOAT*)(c_player + CPlayerAngleOffset) * 0.0174532925199433;
						// pos
						tmp_x = *(FLOAT*)(c_player + CPlayerFootSyncOffset + offsetof(OnFootSync,PosX)) + (f_x * sin(-f_y)); 
						tmp_y = *(FLOAT*)(c_player + CPlayerFootSyncOffset + offsetof(OnFootSync,PosY)) + (f_x * cos(-f_y));
						tmp_z = *(FLOAT*)(c_player + CPlayerFootSyncOffset + offsetof(OnFootSync,PosZ));
						// attacked
						Attacked[pid] = 1;
						// type
						type = DAMAGE_TYPE_GRENADE;
					}
					break;
				}
			}
			if((type == 0) && (check_knock == 0)) continue;

			// npcs
			for(npcid = 0;npcid < MAX_NPCS;npcid++)
			{
				// if valid
				if(!NPC[npcid]) continue;
				// if active
				if(!NPC[npcid]->IsActive()) continue;
				// if not impregnable
				if(NPC[npcid]->IsImpregnable()) continue;
				// if I
				if(npcid == pid) continue;
				// streamed in
				if(NPC[pid])
				{
					NPC[npcid]->GetPos(&range[0],&range[1],&range[2]);
					range[0] -= *(FLOAT*)(c_player + CPlayerPosXOffset);
					range[1] -= *(FLOAT*)(c_player + CPlayerPosYOffset);
					range[2] -= *(FLOAT*)(c_player + CPlayerPosZOffset);
					if(!IsInRange(range[0],range[1],range[2],300.0)) continue;
				}
				else if(*(BYTE*)(c_player + CPlayerIsStreamedOffset + npcid) == 0) continue;
				// get health
				health = NPC[npcid]->GetHealth();
				// if die
				if(health <= 0.0) continue;
				// knock
				if(check_knock == 1) NPC[npcid]->VehicleKnock(pid,pos_x,pos_y,pos_z,v_x,v_y,v_z);
				// if none weapon dmg
				if(type == 0) continue;
				// switch type
				switch(type)
				{
				case DAMAGE_TYPE_RAKET_FROM_VEHICLE:
				case DAMAGE_TYPE_BULLET_FROM_VEHICLE:
				case DAMAGE_TYPE_BULLET_FROM_PASSENGER:
					{
						if(NPC[npcid]->VehicleDamage(pid,tmp_x,tmp_y,tmp_z,f_x,f_y,f_z,health,weapon,type)) goto end_check;
						break;
					}
				case DAMAGE_TYPE_RAKET:
				case DAMAGE_TYPE_GRENADE:
				case DAMAGE_TYPE_MEELE:
				case DAMAGE_TYPE_BULLET:
					{
						if(NPC[npcid]->WeaponDamage(pid,tmp_x,tmp_y,tmp_z,f_x,f_y,f_z,health,weapon,type)) goto end_check;
						break;
					}
				}
			}
			// goto point
			end_check:
			if((StartAgility[pid] != 0) && (keystate == 0))
			{				
				// agility null
				StartAgility[pid] = 0;
				EndAgility[pid] = 0;
			}
		}
		SLEEP(10);
	}
THREAD_END